﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ReconCaracteres_Backpropagation
{
    public class Layer
    {
        public Neuron[] neurons;
        public Layer previousLayer;
        public Layer(Layer previousLayer,int neuronsAmount, int neuronsAmountNexLayer)
        {
            
                this.previousLayer = previousLayer;
                neurons = new Neuron[neuronsAmount];
                for (int i = 0; i < neuronsAmount; i++)
                {
                    if (neuronsAmountNexLayer != 0)
                    {
              
                            neurons[i] = new Neuron(neuronsAmountNexLayer - 1);
                    }
                    else {
                        neurons[i] = new Neuron();//because outputlayer doesnt have weights
                    }
                }
                this.neurons[0].net = 1;//umbral
        }
        public void setInputs(Double[] inputVector){
            for (int i = 1; i < this.neurons.Count(); i++)
            {
                this.neurons[i].net = inputVector[i - 1];//por el umbral que siempre es 1
            }
        }
        public void loadAllInputWeights(String fileName){
            for (int i = 0; i < this.neurons.Count(); i++)
            {
                this.loadInputWeights(i, fileName);
            }
        }
        public void loadInputWeights(int neuronIndex, String fileName)
        {
            WeightsPool w = new WeightsPool();
            Double[] weights = w.readInputWeights(neuronIndex, fileName);
            for (int i = 0; i < this.neurons[neuronIndex].weights.Count(); i++)
            {
                this.neurons[neuronIndex].weights[i] = weights[i];
            }
        }
        public void loadAllOutputWeights(String fileName)
        {
            for (int i = 0; i < this.neurons.Count(); i++)
            {
                this.loadOutputWeights(i, fileName);
            }
        }
        public void loadOutputWeights(int neuronIndex, String fileName)
        {
            WeightsPool w = new WeightsPool();
            Double[] weights = w.readOutputWeights(neuronIndex, fileName);
            for (int i = 0; i < this.neurons[neuronIndex].weights.Count(); i++)
            {
                this.neurons[neuronIndex].weights[i] = weights[i];
            }
        }
        public void computeAllNets(){
            for (int i = 1; i < neurons.Count(); i++)
            {
                this.neurons[i].net = achatar(this.computeNet(i));
             //   Console.Write("["+this.neurons[i].net+"]");
            }
          //  Console.WriteLine("***");
        }
        public Double achatar(Double net)
        { 
            return 1/(1+Math.Pow(Math.E,net*-1));
        }
        public double computeNet(int i){
            double result=0;
            for(int j=0; j<this.previousLayer.neurons.Count(); j++){
                result+=this.previousLayer.neurons[j].net*this.previousLayer.neurons[j].weights[i-1];
            }
            return result;
        }
        public void modifyWeights(Double[] factoresDeCambio, Double alpha) {
            for (int i = 0; i < this.neurons.Count(); i++)
            {
                this.neurons[i].modifyWeigths(factoresDeCambio, alpha);
            }
        }
    }
}
